home *** CD-ROM | disk | FTP | other *** search
- /*
- * @(#)invocCache.c 1.1 6/29/87
- */
- #include "assert.h"
- #include "nodes.h"
- #include "symbols.h"
- #include "sequence.h"
- #include "system.h"
- #include "trace.h"
- #include "opNames.h"
- #include "option.h"
- #include "ndbm.h"
-
- /*
- * Imported routines.
- */
- extern NodePtr
- findManifestValue(),
- figureOutAT(),
- findObjectOperation(),
- OTLookup();
-
- extern Boolean
- isPossibleAnswer();
- extern void
- scheduleOutput(),
- ensureGenerate();
- DBM *emDBM;
-
- static Boolean buildKey(target, opName, formals, args, thekeyptr)
- NodePtr target, opName, formals, args;
- char *thekeyptr;
- {
- NodePtr arg, formal, exp;
- char *thekey = thekeyptr;
- Boolean foundTypeVariable = FALSE;
- #define ADD1(s) {sprintf(thekey, s); thekey += strlen(thekey); }
- #define ADD2(s, v) {sprintf(thekey, s, v); thekey += strlen(thekey); }
- if (target->b.oblit.f.isTypeVariable ||
- target->b.oblit.f.dependsOnTypeVariable) {
- foundTypeVariable = TRUE;
- }
- ADD2("O0x%08x.", target->b.oblit.id);
- ADD2("0x%08x[", opName->b.opname.id);
- Sequence_For(arg, args)
- formal = formals->b.children[z__z];
- assert(arg->tag == P_ARG);
- exp = arg->b.arg.exp;
- exp = findManifestValue(exp);
- assert(exp != NN);
- assert(exp->tag == P_ATLIT || exp->tag == P_OBLIT);
- if (formal->b.param.constraint != NN) {
- /*
- * this is a parameter that is to be a type, so figure the type of
- * the argument.
- */
- exp = figureOutAT(exp);
- assert(exp->tag == P_ATLIT);
- }
- if (exp->b.oblit.f.isTypeVariable ||
- exp->b.oblit.f.dependsOnTypeVariable) {
- foundTypeVariable = TRUE;
- }
- ADD2("O0x%08x", exp->b.oblit.id);
- if (z__z < Sequence_Length(args) - 1) ADD1(",");
- Sequence_Next
- ADD1("]");
- #undef ADD1
- #undef ADD2
- return(foundTypeVariable);
- }
-
- NodePtr checkInvocCache(p)
- NodePtr p;
- {
- NodePtr theOp, theSig, formals, target, opName, result = NN, args;
- char thekeyspace[200], thevaluespace[32];
- datum keydatum, valuedatum;
- OID resultOID;
- Boolean foundTypeVariable = FALSE;
-
- assert(p->tag == P_INVOC);
- target = p->b.invoc.target;
- target = findManifestValue(target);
- assert(target->tag == P_OBLIT);
- opName = p->b.invoc.opname;
- assert(opName->tag == P_OPNAME);
- TRACE3(invoccache, 1,
- "looking in cache for invocation \"%s\" on \"%s\" on line %d",
- ON_Name(opName->b.opname.id),
- ST_SymbolName(target->b.oblit.name->b.symdef.symbol),
- opName->lineNumber);
-
- if (target->b.oblit.id == 0) {
- TRACE0(invoccache, 1, "Cannot execute invocation on oblit without id");
- return(NN);
- }
-
-
- theOp = findObjectOperation(target, opName);
- assert(theOp != NN);
- assert(theOp->tag == P_OPDEF);
-
- theSig = theOp->b.opdef.sig;
- assert(theSig->tag == P_OPSIG);
- formals = theSig->b.opsig.params;
- args = p->b.invoc.args;
- /*
- * First try to see if the invocation has been done previously by some
- * other compiler since the beginning of time.
- */
- foundTypeVariable = buildKey(target, opName, formals, args, thekeyspace);
- if (foundTypeVariable) {
- TRACE0(invoccache, 2, "EI: Non-manifest arguments (or target)");
- }
- TRACE1(invoccache, 2, "EI: The key is %s", thekeyspace);
- keydatum.dptr = thekeyspace;
- keydatum.dsize = strlen(thekeyspace);
- valuedatum = dbm_fetch(emDBM, keydatum);
- TRACE2(invoccache, 2, "The result of fetch = \"%.*s\"", valuedatum.dsize,
- valuedatum.dptr);
- if (valuedatum.dptr != NULL) {
- bcopy(valuedatum.dptr, thevaluespace, valuedatum.dsize);
- *(thevaluespace+valuedatum.dsize) = '\0';
- if (sscanf(thevaluespace, "O0x%x", &resultOID) != 1) assert(FALSE);
- TRACE1(invoccache, 2, "Found it, result OID 0x%08x", resultOID);
- if (! isPossibleAnswer(resultOID, keydatum)) {
- TRACE0(invoccache, 2, "That is not a possible answer.");
- } else {
- result = OTLookup(resultOID);
- }
- }
- if (result == NN) {
- TRACE0(invoccache, 1, "Did not find it");
- } else {
- TRACE2(invoccache, 1, "Result object = 0x%08x %s", result, ATName(result));
- }
- return(result);
- }
-
- void updateInvocCache(p, answer)
- NodePtr p, answer;
- {
- NodePtr theOp, theSig, formals, target, opName, args;
- char thekeyspace[200], thevaluespace[32];
- datum keydatum, valuedatum;
- Boolean foundTypeVariable = FALSE;
-
- assert(p->tag == P_INVOC);
- target = p->b.invoc.target;
- target = findManifestValue(target);
- assert(target->tag == P_OBLIT);
- opName = p->b.invoc.opname;
- assert(opName->tag == P_OPNAME);
- TRACE3(invoccache, 1,
- "caching answer for invocation \"%s\" on \"%s\" on line %d",
- ON_Name(opName->b.opname.id),
- ST_SymbolName(target->b.oblit.name->b.symdef.symbol),
- opName->lineNumber);
-
- if (target->b.oblit.id == 0) {
- TRACE0(invoccache, 1, "Cannot execute invocation on oblit without id");
- }
-
- theOp = findObjectOperation(target, opName);
- assert(theOp != NN);
- assert(theOp->tag == P_OPDEF);
-
- theSig = theOp->b.opdef.sig;
- assert(theSig->tag == P_OPSIG);
- formals = theSig->b.opsig.params;
- args = p->b.invoc.args;
-
- /*
- * Now, put the result in the data base.
- */
- foundTypeVariable = buildKey(target, opName, formals, args, thekeyspace);
- if (foundTypeVariable) {
- TRACE0(invoccache, 2, "EI: Non-manifest arguments (or target)");
- }
-
- keydatum.dptr = thekeyspace;
- keydatum.dsize = strlen(thekeyspace);
-
- assert(answer != NULL);
- answer = GETVALUE(answer);
- assert(answer->tag == P_OBLIT || answer->tag == P_ATLIT);
-
- assert(answer->b.oblit.id != 0);
- sprintf(thevaluespace, "O0x%08x", answer->b.oblit.id);
- valuedatum.dptr = thevaluespace;
- valuedatum.dsize = strlen(thevaluespace);
- TRACE2(invoccache, 1, "storing %s with key %s", ATName(answer),
- keydatum.dptr);
- if (dbm_store(emDBM, keydatum, valuedatum, DBM_REPLACE) < 0) assert(FALSE);
- if (!foundTypeVariable) {
- scheduleOutput(answer->b.oblit.id);
- ensureGenerate(answer->b.oblit.id);
- }
- }
-